package org.example.Thread01;

public class MyBlockingQueue {
    //定义一个数组来存放数据，具体容量由构造方法中的参数决定
    private Integer[] elementData=null;
    //定义头尾下标
    private volatile int head=0;
    private volatile int tail=0;
    //定义数组中元素个数
    private volatile int size=0;
    //构造
    public MyBlockingQueue(int capacity){
        if(capacity<=0){
            throw new ArrayIndexOutOfBoundsException("队列容量必须大于等于0.");
        }
        elementData=new Integer[capacity];
    }

    //插入数据的方法
    public synchronized void put(int value) throws InterruptedException {
        //先判断队列是否已满
        while(size>=elementData.length){
            //阻塞队列在队列满的时候应该阻塞等待
            this.wait();
        }
        //在队列尾部插入元素
        elementData[tail]=value;
        //移动队尾下标
        tail++;
        //处理队尾下标
        if(tail>= elementData.length){
            tail=0;
        }
        //修改size的值
        size++;
        //唤醒阻塞线程
        this.notifyAll();
    }

    //获取数据的方法
    public synchronized Integer take() throws InterruptedException {
        //判断队列是否为空
        if(size==0){
            this.wait();
        }
        //获取要出队的元素
        Integer value=elementData[head];
        //移动队头下标
        head++;
        //处理队头下标
        if(head>=elementData.length){
            head=0;
        }
        //处理数组中元素个数
        size--;
        //唤醒阻塞等待的线程
        this.notifyAll();
        //返回元素
        return value;
    }
}
